package com.atguigu.tingshu.user.service.impl;

import com.atguigu.tingshu.album.client.TrackInfoFeignClient;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.user.*;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.user.mapper.*;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.LocalDateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private UserPaidAlbumMapper userPaidAlbumMapper;

    @Autowired
    private UserPaidTrackMapper userPaidTrackMapper;

    @Autowired
    private TrackInfoFeignClient trackInfoFeignClient;

    @Autowired
    private UserVipServiceMapper userVipServiceMapper;

    @Autowired
    private VipServiceConfigMapper vipServiceConfigMapper;

    @Autowired
    private UserInfoFeignClient userInfoFeignClient;

    @Override
    public void updateVipExpireStatus() {
        //  sendMsgToUser();
//        Date date = new LocalDateTime(new Date()).plusDays(2).toDate();
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getIsVip,1);
        wrapper.le(UserInfo::getVipExpireTime,new Date());
        List<UserInfo> list = this.list(wrapper);
        //  循环遍历
        if (!CollectionUtils.isEmpty(list)){
            //            list.forEach(userInfo -> {
            //                userInfo.setIsVip(0);
            //                //  循环修改
            //                userInfoMapper.updateById(userInfo);
            //            });
            list = list.stream().map(userInfo -> {
                userInfo.setIsVip(0);
                return userInfo;
            }).collect(Collectors.toList());

            //  批量修改：
            this.updateBatchById(list);
        }
    }

    /**
     * 查询即将过期的账户信息
     */
    private void sendMsgToUser() {
        //  提前通知： vipExpire-2=new Date();差两天
        //  查询条件：
        Date date = new LocalDateTime(new Date()).plusDays(2).toDate();
        LambdaQueryWrapper<UserInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfo::getIsVip,1);
        wrapper.eq(UserInfo::getVipExpireTime,date);
        List<UserInfo> list = this.list(wrapper);
        list.stream().forEach(System.out::println);
        //  调用发送短信接口：sendPhoneMsg(userInfo.getPhone(),“vip即将过期，请立即续费...”);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserPaidRecord(UserPaidRecordVo userPaidRecordVo) {
        //  根据购买类型判断向哪张表插入数据.
        if (userPaidRecordVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_ALBUM)){
            //  专辑 user_paid_album
            //  防止重复添加.
            LambdaQueryWrapper<UserPaidAlbum> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserPaidAlbum::getUserId,userPaidRecordVo.getUserId());
            //  wrapper.eq(UserPaidAlbum::getAlbumId,userPaidRecordVo.getItemIdList().get(0));
            wrapper.eq(UserPaidAlbum::getOrderNo,userPaidRecordVo.getOrderNo());
            UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(wrapper);
            if (null != userPaidAlbum){
                return;
            }
            //  新增：
            userPaidAlbum = new UserPaidAlbum();
            userPaidAlbum.setUserId(userPaidRecordVo.getUserId());
            userPaidAlbum.setOrderNo(userPaidRecordVo.getOrderNo());
            //  专辑Id 声音Id vip_service_config.id ==> order_detial.item_id;
            userPaidAlbum.setAlbumId(userPaidRecordVo.getItemIdList().get(0));
            userPaidAlbumMapper.insert(userPaidAlbum);
        }else if (userPaidRecordVo.getItemType().equals(SystemConstant.ORDER_ITEM_TYPE_TRACK)){
            //  声音 user_paid_track
            LambdaQueryWrapper<UserPaidTrack> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UserPaidTrack::getUserId,userPaidRecordVo.getUserId());
            wrapper.eq(UserPaidTrack::getOrderNo,userPaidRecordVo.getOrderNo());
            Long count = userPaidTrackMapper.selectCount(wrapper);
            if (count>0){
                return;
            }
            //  获取专辑Id
            Result<TrackInfo> trackInfoResult = trackInfoFeignClient.getTrackInfo(userPaidRecordVo.getItemIdList().get(0));
            TrackInfo trackInfo = trackInfoResult.getData();
            //  声音Id 有可能一次购买多个.需要循环遍历
            userPaidRecordVo.getItemIdList().stream().forEach(trackId->{
                //  保存数据：
                UserPaidTrack userPaidTrack = new UserPaidTrack();
                userPaidTrack.setTrackId(trackId);
                userPaidTrack.setOrderNo(userPaidRecordVo.getOrderNo());
                userPaidTrack.setUserId(userPaidRecordVo.getUserId());
                //  获取专辑Id
                userPaidTrack.setAlbumId(trackInfo.getAlbumId());
                userPaidTrackMapper.insert(userPaidTrack);
            });
        }else {
            //  vip user_vip_service 保存： vip:续期
            //  获取用户对象信息.
            UserInfo userInfo = userInfoMapper.selectById(userPaidRecordVo.getUserId());
            //  系统时间
            Date currentTime = new Date();
            //  判断是否要做续期：
            if (userInfo.getIsVip().intValue()==1 && userInfo.getVipExpireTime().after(new Date())){
                //  续期：
                currentTime = userInfo.getVipExpireTime();
            }
            VipServiceConfig vipServiceConfig = vipServiceConfigMapper.selectById(userPaidRecordVo.getItemIdList().get(0));
            Integer serviceMonth = vipServiceConfig.getServiceMonth();
            //  LocalDate LocalDateTime LocalTime
            Date expireTime = new LocalDateTime(currentTime).plusMonths(serviceMonth).toDate();
            //  创建对象
            UserVipService userVipService = new UserVipService();
            userVipService.setOrderNo(userPaidRecordVo.getOrderNo());
            userVipService.setUserId(userPaidRecordVo.getUserId());
            userVipService.setStartTime(new Date());
            //--------------> 购买的时长:
            userVipService.setExpireTime(expireTime);
            //  保存
            userVipServiceMapper.insert(userVipService);
            //  修改user_info.is_vip=1;
            userInfo.setIsVip(1);
            //  设置过期时间
            userInfo.setVipExpireTime(expireTime);
            //  手动模拟异常信息。
            int i = 1/0;
            //  修改
            this.userInfoMapper.updateById(userInfo);
        }
    }

    @Override
    public List<Long> findUserPaidTrackList(Long albumId, Long userId) {
        List<Long> trackIdList = new ArrayList<>();
        //	user_paid_track -- 记录着用户购买专辑对应的声音Id.
        //	select * from user_paid_track where album_id = ? and user_id = ?;
        LambdaQueryWrapper<UserPaidTrack> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserPaidTrack::getAlbumId,albumId).eq(UserPaidTrack::getUserId,userId);
        List<UserPaidTrack> userPaidTrackList = userPaidTrackMapper.selectList(wrapper);
        if (!CollectionUtils.isEmpty(userPaidTrackList)){
            //  返回数据。
           trackIdList = userPaidTrackList.stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());
        }
        return trackIdList;
        //  return userPaidTrackMapper.selectList(new LambdaQueryWrapper<UserPaidTrack>().eq(UserPaidTrack::getAlbumId, albumId).eq(UserPaidTrack::getUserId, userId)).stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());
    }

    @Override
    public Boolean isPaidAlbum(Long albumId, Long userId) {
        //	user_paid_album
        //	select * from user_paid_album where user_id = ? and album_id = ?;
        UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(new LambdaQueryWrapper<UserPaidAlbum>().eq(UserPaidAlbum::getAlbumId, albumId).eq(UserPaidAlbum::getUserId, userId));
        //	返回结果
        return null == userPaidAlbum ? false : true;
    }

    /**
     * @param albumId     专辑Id
     * @param trackIdList 专辑Id对应的声音列表。
     * @param userId      用户Id
     * @return
     */
    @Override
    public Map<Long, Integer> userIsPaidTrack(Long albumId, List<Long> trackIdList, Long userId) {
        // 获取用户是否购买过专辑 user_paid_album 或声音Id user_paid_track
        UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(new LambdaQueryWrapper<UserPaidAlbum>().eq(UserPaidAlbum::getAlbumId, albumId).eq(UserPaidAlbum::getUserId, userId));
        //	判断这个专辑对象是否为空.
        if (null != userPaidAlbum) {
            //	购买了专辑.所有的声音Id 都免费. key=trackId,value=1
            //			Map<Long, Integer> map = new HashMap<>();
            //			for (Long trackId : trackIdList) {
            //				map.put(trackId,1);
            //			}
            //			return map;
            Map<Long, Integer> map = trackIdList.stream().collect(Collectors.toMap(trackId -> trackId, trackId -> 1));
            //	返回数据
            return map;
        }
        //	判断用户是否购买过声音Id.
        //	select * from user_paid_track where user_id = 26 and track_id in (48246,48247,48888);
        //	获取用户购买的声音集合对象 48246,48247
        //	判断：所以需要付费的声音Id 是否包含用户购买的声音Id
        HashMap<Long, Integer> map = new HashMap<>();
        //	获取数据
        List<UserPaidTrack> userPaidTrackList = userPaidTrackMapper.selectList(new LambdaQueryWrapper<UserPaidTrack>().eq(UserPaidTrack::getUserId, userId).in(UserPaidTrack::getTrackId, trackIdList));
        if (!CollectionUtils.isEmpty(userPaidTrackList)) {
            //	获取到用户购买过声音Id 集合
            List<Long> userPaidTrackIdList = userPaidTrackList.stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());
            //	循环遍历
            trackIdList.stream().forEach(trackId -> {
                //	判断
                //				if (userPaidTrackIdList.contains(trackId)){
                //					map.put(trackId,1);
                //				}else {
                //					map.put(trackId,0);
                //				}
                Integer value = userPaidTrackIdList.contains(trackId) ? 1 : 0;
                //	存储数据
                map.put(trackId, value);
            });
        } else {
            //	没有购买过任何记录信息。
            trackIdList.stream().forEach(trackId -> {
                //	存储数据
                map.put(trackId, 0);
            });
        }
        //	返回map集合
        return map;
    }

    @Override
    public UserInfo getUserInfoVo(Long userId) {
        return userInfoMapper.selectById(userId);
        //	return this.getById(userId);
    }

    @Override
    public void updateUser(UserInfoVo userInfoVo, Long userId) {
        //	创建对象
        UserInfo userInfo = new UserInfo();
        //	属性拷贝：
        BeanUtils.copyProperties(userInfoVo, userInfo);
        userInfo.setId(userId);
        //	修改方法
        userInfoMapper.updateById(userInfo);
    }

    @Override
    public UserInfoVo getUserInfoById(Long userId) {
        //	获取用户信息
        UserInfo userInfo = this.getById(userId);
        //	创建UserInfoVo 对象
        UserInfoVo userInfoVo = new UserInfoVo();
        //	属性拷贝：
        BeanUtils.copyProperties(userInfo, userInfoVo);
        return userInfoVo;
    }
}
